A debugger is a computer program that is used to test and debug other programs. When the program crashes, the debugger shows the position in the original code if it is a source-level debugger or symbolic debugger, commonly seen in integrated development environments. If it is a low-level debugger or a machine-language debugger, it shows the line in the disassembly that occurs if a “crash” happens when the program cannot continue because of a programming bug. Conventional debuggers also offer more sophisticated functions such as running a program step by step (single-stepping), stopping (breaking or pausing the program to examine the current state) at some kind of event by means of breakpoint, and tracking the values of some variables. Some debuggers have the ability to modify the state of the program while it is running, rather than merely observe it.
Debuggers make the debugging process much easier and faster, to the point where the availability of a good debugger for a particular language and platform can sway the decision to use that language rather than another language that is superior in other respects but lacks such tools.
A significant limitation of existing debuggers is that software running under a debugger typically behaves differently than software running normally, because a debugger changes the internal timing of a software program. That makes it often very difficult to track down runtime problems in complex multi-threaded or distributed systems.
In a multi-tiered environment (e.g., a client-server environment), conventional debuggers typically operate using a window on the client side and a window on the server side. The problem with this approach is that it requires the user to keep the two windows open and in-sync during the entire debugging process. Another common scheme is to build the debugger into the design-time tooling environment. However, this makes tracking debugging problems occurring in the production environment more difficult. In addition, design-time debuggers usually connect to the runtime engine, and have the problem of synchronized display of the debugger and end-user user interfaces.